#include "scene.hpp"

Scene::Scene(const Color& _background,const double _ambient) : background(_background), ambient(_ambient) {
	attenuation = false;
	a = b = c = 0;
}

Scene::~Scene() { }

int Scene::nearest_object(Vector& _point,const Ray& _ray) {
	double distancia = 90.1;
	int j = -1;
	Vector test_point;
	for(int i =0;i<get_objectsEnd();i++) {
		double valor = get_object(i)->intersection(_ray,test_point);
		if(valor != 90.0 && valor < distancia) { /* Searching the nearest */
			j= i;
			distancia = valor;
			_point = test_point;
		}
	}	
	return j;
}

bool Scene::object_occlusion(const Ray& _ray,const double _t) {
	Vector point;
	for(int i =0;i<get_objectsEnd();i++) {
            if(get_object(i)->intersection(_ray,point) < _t ) return true;
	}
	return false;
}	

void Scene::add_objectlist(vector<Object*>* _objectlist) {
	for(unsigned int i =0;i<_objectlist->size();i++) {
		add_object((*_objectlist)[i]);
	}
}

void Scene::add_object(Object* _object) { objects.push_back(_object); }

void Scene::add_lightlist(vector<Light*>* _lightlist) {
	for(unsigned int i =0;i<_lightlist->size();i++) {
		add_light((*_lightlist)[i]);
	}
}

void Scene::add_light(Light* _light) { lights.push_back(_light); }

void Scene::set_background(const Color& _background) { background = _background; }

void Scene::set_attenuation(bool _attenuation) { attenuation = _attenuation; }

void Scene::set_attenuation(double _a,double _b,double _c) {
	a = _a;
	b = _b;
	c = _c;
	attenuation = true;
}

void Scene::set_ambient(double _ambient) { ambient = _ambient; }

int Scene::get_objectsEnd(void) const { return objects.size(); }

int Scene::getLightesEnd(void) const { return lights.size(); }

Object* Scene::get_object(const int _index) const { return objects[_index]; }

Light* Scene::get_light(const int _index) const { return lights[_index]; }

Color Scene::get_background(void) const { return background; }

double Scene::get_attenuation(const double _t) const {
	 if(attenuation) return 1.0/(a*_t*_t + b*_t + c); 
	 else return 1.0; 
}

double Scene::get_attenuation_value(const unsigned short _index) const {
	switch(_index) {
		case 1: return a;
		case 2: return b;
		case 3: return c;
	}
}

double Scene::get_ambient(void) const {
	return ambient;
}
